﻿using DataMgr.CapSel;
using DataMgr.Export;
using DataMgr.msg;
using DataMgr.msg.rsp;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DataMgr
{
    class SocketServer
    {
        //接收数据的线程
        private static Thread receiveThread;
        private static Socket m_socketLister = null;
        private static Hashtable m_clientSessionTable = new Hashtable();
        public bool Start()
        {
            int port = 26000;

            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);
            m_socketLister = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            m_socketLister.Bind(localEndPoint);

            //初始化线程
            receiveThread = new Thread(new ThreadStart(TcpReceive));
            receiveThread.Start();//启动
            return true;
        }

        public static void TcpReceive()
        {
            try
            {
                m_socketLister.Listen(0);
                object clientSessionLock = new object();
                while (true)
                {
                    Socket clientSocket = m_socketLister.Accept();

                    //Thread thr = new Thread(RecMsg);
                    //thr.IsBackground = true;
                    //thr.Start(clientSocket);

                    ClientSession clientSession = new ClientSession(clientSocket);
                    //lock (clientSessionLock)
                    //{
                    //    if (!m_clientSessionTable.ContainsKey(clientSession.IP))
                    //    {
                    //        m_clientSessionTable.Add(clientSession.IP, clientSession);
                    //    }
                    //}

                    MsgUtil.WriteLog("建立连接：" + clientSession.IP);
                    SocketConnection socketConnection = new SocketConnection(clientSocket);
                    socketConnection.ReceiveData();
                    //Thread.Sleep(300);
                    //string recStr = "";
                    //recStr += Encoding.ASCII.GetString(socketConnection.msgBuffer);
                    //MsgUtil.WriteLog("服务器获得信息："+ recStr);
                }
            }
            catch (SocketException ex)
            {
                MsgUtil.WriteLog(ex.ToString());
            }

            MsgUtil.WriteLog("监听服务退出");
        }
        //接收消息
        static void RecMsg(object sokConnectionparn)
        {
            Socket clientSocket = sokConnectionparn as Socket;
            ClientSession clientSession = new ClientSession(clientSocket);
            MsgUtil.WriteLog("建立连接：" + clientSession.IP);
            while (true)
            {
                //byte[] arrMsgRec = new byte[1024 * 1024];
                // 将接受到的数据存入到输入  arrMsgRec中；
                try
                {
                    SocketConnection socketConnection = new SocketConnection(clientSocket);
                    socketConnection.ReceiveData();
                    //int iLength = sokClient.Receive(arrMsgRec);
                    //string sStrReceMsg = Encoding.UTF8.GetString(arrMsgRec, 1, iLength);
                    //MsgUtil.WriteLog(sStrReceMsg);
                    //string specialString = "DiChuang_te\0";
                    //string[] sArr = sStrReceMsg.Split(';');

                    //string sSqlPath = "D://LoginDB.db";
                    //TeSQLite teSQL = new TeSQLite();
                    //teSQL.teConnDB(sSqlPath);
                    //if (teSQL.teCompareD(sArr[0], sArr[1]) && sArr[2] == specialString)
                    //{
                    //    string returnStr = "A";
                    //    byte[] byteArray = System.Text.Encoding.Default.GetBytes(returnStr);
                    //    sokClient.Send(byteArray);
                    //}
                    //else
                    //{
                    //    string returnStr = "B";
                    //    byte[] byteArray = System.Text.Encoding.Default.GetBytes(returnStr);
                    //    sokClient.Send(byteArray);
                    //}
                }
                catch (SocketException ex)
                {
                    MsgUtil.WriteLog(ex.ToString());
                }
            }
        }
        public static void OnRecData(SocketConnection con,string msg)
        {
            Console.WriteLine("OnRecData：{0} tid{1}", msg, Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }
    public class ClientSession
    {
        public Socket ClientSocket { get; set; }
        public string IP;
        public ClientSession(Socket clientSocket)
        {
            this.ClientSocket = clientSocket;
            this.IP = GetIPStr();
        }
        public string GetIPStr()
        {
            string resStr = ((IPEndPoint)ClientSocket.RemoteEndPoint).Address.ToString();
            return resStr;
        }
    }

    public class SocketConnection : IDisposable
    {
        public Byte[] msgBuffer = new byte[1024];
        private Socket _clientSocket = null;
        public event EventHandler RecDataEvent;
        private MsgHead _head = new MsgHead();
        public Socket ClientSocket
        {
            get { return this._clientSocket; }
        }
        #region 构造
        public SocketConnection(Socket sock)
        {
            this._clientSocket = sock;
        }
        #endregion
        #region 连接
        public void Connect(IPAddress ip, int port)
        {
            this.ClientSocket.BeginConnect(ip, port, ConnectCallback, this.ClientSocket);
        }
        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                Socket handler = (Socket)ar.AsyncState;
                handler.EndConnect(ar);
            }
            catch (SocketException ex)
            {
                MsgUtil.WriteLog(ex.ToString());
            }
        }
        #endregion
        #region 发送数据
        public void Send(string data)
        {
            //生成响应报文
            _head.msg_flag = "2";
            //_head.msg_type = "1";
            string sSendMsg = _head.ToString() + data;
            SendGoldMsg(sSendMsg);
            MsgUtil.WriteLog(sSendMsg);
            //Send(System.Text.Encoding.UTF8.GetBytes(sSendMsg));
        }
        /// <summary>
        /// 发送符合系统接口规范的报文
        /// </summary>
        /// <param name="v_sMsg"></param>
        public void SendGoldMsg(string v_sMsg)
        {
            if (v_sMsg == null || v_sMsg.Length <= 0 || _clientSocket == null)
                return;

            v_sMsg = MsgHead.Fill(MsgBase.GetEncoding().GetByteCount(v_sMsg).ToString(), '0', MsgBase.MSG_LEN, 'L') + v_sMsg;

            byte[] sSrcMsg = MsgUtil.ConvertBytes(v_sMsg);

            //不打印报文
            //CommUtil.WriteLog("发送报文:" + MsgUtil.ConvertString(sSrcMsg));

            Send(sSrcMsg);
            //Send(bSendMsg, SocketFlags.None);
        }
        private void Send(byte[] byteData)
        {
            try
            {
                this.ClientSocket.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), this.ClientSocket);
            }
            catch (SocketException ex)
            {
                MsgUtil.WriteLog(ex.ToString());
            }
        }
        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket handler = (Socket)ar.AsyncState;
                handler.EndSend(ar);
            }
            catch (SocketException ex)
            {
                MsgUtil.WriteLog(ex.ToString());
            }
        }
        #endregion
        #region 接收数据
        public void ReceiveData()
        {
            ClientSocket.BeginReceive(msgBuffer, 0, msgBuffer.Length, 0, new AsyncCallback(ReceiveCallback), null);
            //string recStr = "";

            //recStr = MsgBase.GetEncoding().GetString(msgBuffer);
            //MsgUtil.WriteLog("BeginReceive:"+recStr.Trim());
        }
        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                int REnd = ClientSocket.EndReceive(ar);
                if (REnd > 0)
                {
                    byte[] data = new byte[REnd];
                    Array.Copy(msgBuffer, 0, data, 0, REnd);

                    //在此处对数据进行处理

                    ClientSocket.BeginReceive(msgBuffer, 0, msgBuffer.Length, 0, new AsyncCallback(ReceiveCallback), null);

                    MsgUtil.WriteLog("数据接收线程："+ Thread.CurrentThread.ManagedThreadId.ToString());

                    string recStr = "";
                    recStr = MsgBase.GetEncoding().GetString(data);
                    //recStr = Encoding.UTF8.GetString(data);
                    //recStr = Encoding.Unicode.GetString(data);
                    //recStr = Encoding.GetEncoding("GBK").GetString(data);
                    while (true)
                    {
                        string lenStr = recStr.Substring(0, MsgBase.MSG_LEN);
                        int nbodyLen = Int32.Parse(lenStr);
                        int nPktLen = MsgBase.GetLength(recStr);    //带中文的要使用专门的方法取长度
                        //string pktString = recStr.Substring(0, nbodyLen + MsgBase.MSG_LEN);
                        string pktString = MsgBase.SubString(recStr, 0, nbodyLen + MsgBase.MSG_LEN);
                        Deliver(pktString);
                        recStr = MsgBase.SubString(recStr, nbodyLen + MsgBase.MSG_LEN, nPktLen -nbodyLen - MsgBase.MSG_LEN); //recStr.Substring(nbodyLen + MsgBase.MSG_LEN);
                        if (recStr == null || recStr.Length < MsgBase.MSG_LEN)
                            break;
                    }

                }
                else
                {
                    Dispose();
                }
            }
            catch (SocketException ex)
            {
                MsgUtil.WriteLog(ex.ToString());
            }
        }

        void Deliver(string recStr)
        {
            _head.Parse(recStr);
            MsgUtil.WriteLog(recStr);
            if (_head.exch_code == "DOWN")
            {
                int nRet = DownManager.RecDownMsg(recStr);
                string sRsp = "0000";
                Send(sRsp);
            }
            else if (_head.exch_code == "D001")
            {
                int nRet = BdfExport.RecExportMsg(recStr);
                string sRsp = "0000";
                if (0 != nRet)
                    sRsp = "0001";

                Send(sRsp);
            }
            else if (_head.exch_code == "D002")
            {
                RspExportProgress rsp = BdfExport.QueryExportMsg(recStr);
                Send("0000"+rsp.ToString());
            }
            else if (_head.exch_code == "D003")
            {
                RspCapSelValue rsp = CapSelMgr.QueryCapSel(recStr);
                Send("0000" + rsp.ToString());
            }
        }
        public void Dispose()
        {
            try
            {
                ClientSocket.Shutdown(SocketShutdown.Both);
                ClientSocket.Close();
            }
            catch (Exception ex)
            {
                MsgUtil.WriteLog(ex.ToString());
            }
        }
        #endregion
    }


}